/**
 * Mise en oeuvre de Echiquier.h
 *
 * @file Echiquier.cxx
 */

#include <iostream>
#include "Piece.h"

#include "Echiquier.h"
#include <typeinfo>

using namespace std;

/**
 * Constructeur par defaut.
 * Initialise  a vide l'echiquier.
 */
Echiquier::Echiquier()
{
    for(int i=0; i<=64; i++)
        m_cases[i] = NULL;
}


/**
 * Recupere la piece situee sur une case.
 *
 * @param x un entier entre 1 et 8
 * @param y un entier entre 1 et 8
 *
 * @return 0 si aucune piece n'est sur cette case et un pointeur
 * vers une piece sinon.
 */
Piece*
Echiquier::getPiece( int x, int y )
{
    return m_cases[x - 1 + ( y - 1 ) * 8];
}


/**
 * Place une piece sur l'echiquier, aux coordonnees specifiees dans la piece.
 *
 * @param p un pointeur vers une piece
 *
 * @return 'true' si le placement s'est bien passe, 'false' sinon
 * (case occupee, coordonnees invalides, piece vide )
 */
bool
Echiquier::placer(Piece* p)
{
    int x = p->x();
    int y = p->y();
    int i = x-1+(y-1)*8;

    if ((1 <= p->x()) and (p->x()<=8) and (1 <= p->y()) and (p->y() <=8))
    {
        m_cases[i] = p;
        return true;
    }
    else
        return false;
}


/**
 * Deplace une piece sur l'echiquier, des coordonnees specifiees
 * dans la piece aux coordonnees x,y.
 *
 * @param p un pointeur vers une piece
 * @param x un entier entre 1 et 8
 * @param y un entier entre 1 et 8
 *
 * @return 'true' si le placement s'est bien passe, 'false' sinon
 * (case occupee, coordonnees invalides, piece vide, piece pas
 * presente au bon endroit sur l'echiquier)
 */
bool
Echiquier::deplacer(Piece* p, int x, int y )
{
    int xsup = p->x();
    int ysup = p->y();

    if (p->mouvementvalide(this,x,y))
    {
        p->move(x,y);
        this->placer(p);
        this->enleverPiece(xsup,ysup);

        return true;
    }
    else
        return false;
}


/**
 * Enleve la piece situee sur une case (qui devient vide).
 *
 * @param x un entier entre 1 et 8
 * @param y un entier entre 1 et 8
 *
 * @return NULL si aucune piece n'est sur cette case et le pointeur
 * vers la piece enlevee sinon.
 */
Piece*
Echiquier::enleverPiece( int x, int y )
{

    if ((1 <= x) and (x<=8) and (1 <= y) and (y<=8))
    {
        if (m_cases[x - 1 + ( y - 1 ) * 8] == NULL)
        {
            cout << "x - 1 + ( y - 1 ) * 8";
            return NULL;
        }
        else
        {
            Piece *ptr = m_cases[x - 1 + ( y - 1 ) * 8];
            m_cases[x - 1 + ( y - 1 ) * 8] = NULL;
            return ptr;
        }
    }
}





/**
 * Affiche l'echiquier avec des # pour les cases noires et . pour
 * les blanches si elles sont vides, et avec B pour les pieces
 * blanches et N pour les pieces noires.
 */
void
Echiquier::affiche()
{

    cout << endl << "  12345678" << endl;
    for ( int y = 1; y <= 8; ++y )
    {
        cout << y << " ";
        for ( int x = 1; x <= 8; ++x )
        {
            char c;
            Piece* p = getPiece( x, y );
            if ( p == 0)
            {
                c = ( ( x + y ) % 2 ) == 0 ? '#' : '.';
            }
            else
            {
                c = p->tostring();
            }
            cout << c;

        }
        cout << " " << y << endl;
    }
    cout << "  12345678" << endl;
}

void
Echiquier::remplirm_blanc()
{
    int i = 0;
    int j = 0;
    for(i=0; i<64; i++)
    {
        if(m_cases[i]->isBlack() && m_cases[i] != 0)
        {
            for(j=0; j<64; j++)
            {
                if(m_cases[i]->mouvementvalide(this,m_cases[j]->x(),m_cases[j]->y()) && m_cases[j]==0)
                {
                    m_blanc.push_back(m_cases[j]);
                }
            }
        }
    }

}
void
Echiquier::remplirm_noir()
{
    int i = 0;
    int j = 0;
    for(i=0; i<64; i++)
    {
        if(m_cases[i]->isWhite() && m_cases[i] != 0)
        {
            for(j=0; j<64; j++)
            {
                if(m_cases[i]->mouvementvalide(this,m_cases[j]->x(),m_cases[j]->y()) && m_cases[j]==0)
                {
                    m_noirs.push_back(m_cases[j]);
                }
            }
        }
    }
}
bool
Echiquier::presentm_blanc(int x,int y)
{
    int i;
    bool present = false;
    for(i=0; i <= m_blanc.size(); i++)
    {
        if(m_blanc[i]->x() == x && m_blanc[i]->y() == y)
        {
            present = true;
        }

    }
    return present;
}
bool
Echiquier::presentm_noir(int x,int y)
{
    int i;
    bool present = false;
    for(i=0; i <= m_noirs.size(); i++)
    {
        if(m_noirs[i]->x() == x && m_noirs[i]->y() == y)
        {
            present = true;
        }

    }
    return present;
}



